﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Xml.Linq;
using ajayumi.develop.win32.Transport.Utils;
using ajayumi.develop.win32.Transport.WCF.Services.Interfaces;
using ajayumi.develop.win32.Transport.WCF.Services.DataContracts;
using ajayumi.develop.win32.Transport.WCF.Services;


namespace ajayumi.develop.win32.Transport.WCF.ServiceImpls
{
    /// <summary>
    /// 实现应用程序更新
    /// Author  : 黄乙冬
    /// Date    : 2011-08-31
    /// </summary>
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class UpgradeService : IUpgrade
    {
        #region Variables

        private const string UPGRADE_FILE = "Upgrade.xml";
        private string m_LatestVersion = string.Empty;
        private List<UpgradeItem> m_UpgradeItemList = null;

        #endregion

        public UpgradeService()
        {
            this.m_UpgradeItemList = new List<UpgradeItem>();
            this.LoadData();
        }

        private void LoadData()
        {
            XElement xElement = XElement.Load(UPGRADE_FILE);
            this.m_UpgradeItemList = xElement.Elements("Upgrades").Elements("Upgrade").Select<XElement, UpgradeItem>(o => new UpgradeItem(o)).ToList();
        }

        ///// <summary>
        ///// 获取升级版本
        ///// </summary>
        ///// <param name="appName">应用程序名称</param>
        ///// <returns></returns>
        //private Dictionary<string, UpgradeInfo> GetUpgradeVersion(string appName)
        //{
        //    XElement xElement = XElement.Load(UPGRADE_FILE);
        //    List<UpgradeItem> upgradeItemList = xElement.Elements("Upgrades").Elements("Upgrade").Select<XElement, UpgradeItem>(o => new UpgradeItem(o)).ToList();

        //    IEnumerable<UpgradeItem> upgradeItems = (from item in upgradeItemList
        //                                             where item.AppName.Equals(appName)
        //                                             select item).OrderByDescending(o => o);
        //    Dictionary<string, UpgradeInfo> dict = new Dictionary<string, UpgradeInfo>();
        //    foreach (UpgradeItem item in upgradeItems)
        //    {
        //        dict.Add(item.Version, item.ToUpgradeInfo());
        //    }

        //    return dict;
        //}

        //private UpgradeItem GetLatestUpgradeItem(string appName)
        //{
        //    XElement xElement = XElement.Load(UPGRADE_FILE);
        //    List<UpgradeItem> upgradeItemList = xElement.Elements("Upgrades").Elements("Upgrade").Select<XElement, UpgradeItem>(o => new UpgradeItem(o)).ToList();

        //    IEnumerable<UpgradeItem> upgradeItems = (from item in upgradeItemList
        //                                             where item.AppName.Equals(appName)
        //                                             select item).OrderByDescending(o => o);
        //    UpgradeItem upgradeItem = upgradeItems.First();
        //    return upgradeItem;
        //}


        //public UpgradeInfo GetLatestVersion(string appName)
        //{
        //    UpgradeItem upgradeItem = this.GetLatestUpgradeItem(appName);
        //    UpgradeInfo upgradeInfo = new UpgradeInfo()
        //    {
        //        AppName = upgradeItem.AppName,
        //        Version = upgradeItem.Version,
        //        Description = upgradeItem.Description,
        //        DiffUpgradeFiles = upgradeItem.DiffUpgradeFiles,
        //        FullUpgradeFiles = upgradeItem.FullUpgradeFiles
        //    };
        //    return upgradeInfo;
        //}

        //public string GetLatestVersion(string appName)
        //{
        //    string latestVersion = string.Empty;
        //    this.m_UpgradeInfos = this.GetUpgradeVersion(appName);
        //    if (this.m_UpgradeInfos.Count > 0)
        //    {
        //        UpgradeInfo upgradeInfo = this.m_UpgradeInfos.First().Value;
        //        latestVersion = upgradeInfo.Version;
        //    }
        //    return latestVersion;
        //}

        //public string GetUpgradeDescription(string appName, string version)
        //{
        //    StringBuilder sb = new StringBuilder();
        //    UpgradeInfo[] upgradeInfos = this.GetUpgrades(appName, version);
        //    foreach (UpgradeInfo item in upgradeInfos)
        //    {
        //        sb.AppendFormat("版本：{0}", item.Version);
        //        sb.AppendLine();
        //        sb.AppendLine("=======================================");
        //        sb.AppendLine(item.Description);
        //        sb.AppendLine();
        //    }

        //    return sb.ToString();
        //}


        //public UpgradeInfo[] GetUpgrades(string appName, string version)
        //{
        //    List<UpgradeInfo> lst = new List<UpgradeInfo>();
        //    foreach (KeyValuePair<string, UpgradeInfo> item in this.m_UpgradeInfos)
        //    {
        //        if (item.Value.Version.Equals(version)) break;

        //        lst.Add(item.Value);
        //    }

        //    return lst.ToArray();
        //}


        public CheckUpgradeVerInfo CheckVersion(string appName, string version)
        {
            CheckUpgradeVerInfo result = new CheckUpgradeVerInfo();
            UpgradeItem upgradeItem = (from item in this.m_UpgradeItemList
                                       where item.AppName.Equals(appName)
                                       select item).OrderByDescending(o => o).FirstOrDefault();

            if (upgradeItem != null)
            {
                this.m_LatestVersion = upgradeItem.Version;
                int latestVersion = VersionFormatter.ToInt(upgradeItem.Version);
                int currentVersion = VersionFormatter.ToInt(version);

                result.LatestVersion = upgradeItem.Version;
                result.HasUpgrade = (latestVersion > currentVersion);
                result.IsNeed = upgradeItem.IsNeed;
            }

            return result;
        }


        public UpgradeInfo GetUpgrade(string appName, string version)
        {
            UpgradeInfo upgradeInfo = new UpgradeInfo();
            IEnumerable<UpgradeItem> upgradeItems = (from item in this.m_UpgradeItemList
                                                     where item.AppName.Equals(appName)
                                                     select item).OrderByDescending(o => o);

            UpgradeItem upgradeItem = upgradeItems.FirstOrDefault();
            if (upgradeItem != null)
            {
                upgradeInfo.AppName = upgradeItem.AppName;
                upgradeInfo.Version = upgradeItem.Version;
                upgradeInfo.UpgradeRunMode = upgradeItem.UpgradeRunMode;
                upgradeInfo.UpgradeMode = upgradeItem.UpgradeMode;
                upgradeInfo.FullUpgradeFiles = upgradeItem.FullUpgradeFiles;
            }

            StringBuilder sb = new StringBuilder();
            List<FilePathInfo> diffUpgradeFiles = new List<FilePathInfo>();
            foreach (UpgradeItem item in upgradeItems)
            {
                if (item.Version.Equals(version)) break;

                //合并版本描述字符串
                sb.AppendFormat("版本：{0}", item.Version);
                sb.AppendLine();
                sb.AppendLine("=======================================");
                sb.AppendLine(item.Description);
                sb.AppendLine();

                //去除重复项，由于版本序列已经按照降序排序，所以新版本文件会先保存到列表对象中，然后可以做一个对比即可
                foreach (FilePathInfo fItem in item.DiffUpgradeFiles)
                {
                    bool isExist = diffUpgradeFiles.Exists(o =>
                    {
                        return o.RelativePath.Equals(fItem.RelativePath);
                    });
                    if (!isExist)
                    {
                        diffUpgradeFiles.Add(fItem);
                    }
                }
            }
            upgradeInfo.Description = sb.ToString();
            upgradeInfo.DiffUpgradeFiles = diffUpgradeFiles.ToArray();

            return upgradeInfo;
        }

    }
}
